package com.buba.config;

import com.buba.pojo.User;
import com.buba.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 自定义的UserReaml extends AuthorizingRealm
 */
public class UserReaml extends AuthorizingRealm {

    private UserService userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权doGetAuthorizationInfo");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //拿到当前登录的对象
        Subject subject = SecurityUtils.getSubject();
        //取出登录对象中的用户对象
        User user = (User)subject.getPrincipal();
        //设置当前登录用户的权限
        //设置单个权限
//        info.addStringPermission(user.getPerms());

        //设置多个权限
        //获取权限标识字符串
        String perms =  user.getPerms();
        //切割并转为集合
        String[] permsSplit = perms.split(",");
        List<String> permsList = Arrays.asList(permsSplit);
        //授权
        info.addStringPermissions(permsList);

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("认证doGetAuthenticationInfo");

        //获取token中的登录账号信息
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

        //加密区域
        //获取令牌中的用户名
        String username = userToken.getUsername();
        char[] password = userToken.getPassword();

        //使用MD5加密密码                      //加密方式                     //盐值                              //加密1024次
        String newPassword = new SimpleHash("MD5",password, ByteSource.Util.bytes(username), 1024).toHex();
        //把新密码给token
        userToken.setPassword(newPassword.toCharArray());

        //用户名密码在数据库中取
        User user = userService.queryUserByName(username);
        if(user==null){
            //return null;会抛出UnknownAccountException异常
            return null;
        }

        //添加session
        Subject currentSubject= SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);


        //密码认证由seiro做
        //可以加密 MD5加密 高级md5盐值加密      对象        密码              realmName：当前realm对象的name，调用父类的getName()方法即可
        return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
    }



    /**
     * 测试MD5加密
     * @param args
     */
    public static void main(String[] args) {
        String hashAlgorithmName = "MD5";//加密方式
        Object crdentials = "888";//密码原值
        Object salt = "888";//盐值
        int hashIterations = 1024;//加密1024次
        String result = new SimpleHash(hashAlgorithmName,crdentials, ByteSource.Util.bytes(salt), hashIterations).toHex();
        System.out.println( result);
    }




    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
